#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFile>
#include <QPixmap>
#include <QPainter>
#include <QBitmap>
#include <QSize>
#include <QColor>
#include <QStringList>
#include <QDateTime>
#include <QFileDialog>

#define cout qDebug() << "[" << __FILE__ << ":" << __LINE__ << "]"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //固定窗口尺寸
    setFixedSize( this->width(),this->height());
    ui->start->setText("开始");
    ui->pause->setText("暂停");
    ui->clear_form->setText("清空表");
    ui->save_form->setText("保存表");
    //指示灯变红
    fitpixmap = QPixmap("://images/redlight.png").scaled(51, 51, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
    ui->label_light->setPixmap(pixmap_to_round(fitpixmap,25.5));
    serialport = new QSerialPort;
    windows_init();

    // 显示坐标
    textItem = new QCPItemText(ui->widget);
    connect(ui->widget, &QCustomPlot::mouseMove, this, &MainWindow::onMouseMove);

    connect(ui->checkBox_X, SIGNAL(stateChanged(int)), this, SLOT(checkbox_change()));
    connect(ui->checkBox_Y, SIGNAL(stateChanged(int)), this, SLOT(checkbox_change()));
    connect(ui->checkBox_XY, SIGNAL(stateChanged(int)), this, SLOT(checkbox_change()));



}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::windows_init()
{
    find_serialport();
    //控件初始化
    ui->close_port->setEnabled(false);
    ui->start->setEnabled(false);
    ui->pause->setEnabled(false);
    ui->increase_temp->setEnabled(false);
    ui->decrease_temp->setEnabled(false);

    //lcd初始化
    ui->lcdSetNum->setDigitCount(6); //位数
    ui->lcdSetNum->setMode(QLCDNumber::Dec);    //十进制
    ui->lcdSetNum->setSegmentStyle(QLCDNumber::Flat);       //显示外观
    ui->lcdCurNum->setDigitCount(6); //位数
    ui->lcdCurNum->setMode(QLCDNumber::Dec);    //十进制
    ui->lcdCurNum->setSegmentStyle(QLCDNumber::Flat);       //显示外观
    temperature = 0;
    ui->lcdCurNum->display(temperature);
    set_temperature = 0;
    ui->lcdSetNum->display(set_temperature);
    // 单选框
    QButtonGroup* pButtonGroup = new QButtonGroup(this);
    pButtonGroup->addButton(ui->checkBox_X,1);
    pButtonGroup->addButton(ui->checkBox_Y,2);
    pButtonGroup->addButton(ui->checkBox_XY,3);

    // 表格初始化
    ui->tableWidget->setColumnCount(2);
    ui->tableWidget->setAlternatingRowColors(true);     //设置隔行变颜色
    ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);       //选中整行
    //设置表头
    QStringList header;
    header<<tr("时间")<<tr("温度");
    ui->tableWidget->setHorizontalHeaderLabels(header);
    ui->tableWidget->setColumnWidth(0,120);
    ui->tableWidget->setColumnWidth(1,80);

    //绘图初始化
    // 添加曲线 1
    ui->widget->addGraph();         // 增加图层
    ui->widget->graph(0)->setPen(QPen(Qt::red));
    ui->widget->graph(0)->setBrush(QBrush(QColor(0,0,205,50)));     // 设置图层画刷颜色
    ui->widget->graph(0)->setAntialiasedFill(false);        // 设置图层反锯齿：关闭
    ui->widget->graph(0)->setName("当前温度");

    // 添加点
    ui->widget->addGraph();
    ui->widget->graph(1)->setPen(QPen(Qt::blue,3));       // 设置笔的颜色
    ui->widget->graph(1)->setLineStyle(QCPGraph::lsNone);   // 不画线条
    ui->widget->graph(1)->setScatterStyle(QCPScatterStyle::ssDisc);     // 设置点的形状

    //添加曲线 2
    ui->widget->addGraph();
    ui->widget->graph(2)->setPen(QPen(Qt::yellow));
    ui->widget->graph(2)->setName("设定温度");

    //坐标轴1设置
    QSharedPointer<QCPAxisTickerTime> timeTicker(new QCPAxisTickerTime);
    timeTicker->setTimeFormat("%m:%s");             //时间格式：  秒
    ui->widget->xAxis->setTicker(timeTicker);       // 横坐标显示时间
    ui->widget->axisRect()->setupFullAxesBox();     //坐标为矩
    // x轴设置
    ui->widget->xAxis->setLabel("时间(单位s)");         // 设置横轴标签
    ui->widget->yAxis->setRange(-50,50);       //设置温度范围
    ui->widget->xAxis->setLabel("时间");
    ui->widget->yAxis->setLabel("温度(℃)");
    //ui->widget->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables);    //设置属性可缩放，移动
    ui->widget->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom);    //允许可缩放，移动
    QList < QCPAxis *>  xis;
    xis.append(ui->widget->xAxis);
    ui->widget->axisRect()->setRangeZoomAxes(xis);

    // 轴随动
    connect(ui->widget->xAxis, SIGNAL(rangeChanged(QCPRange)), ui->widget->xAxis2, SLOT(setRange(QCPRange)));
    connect(ui->widget->yAxis, SIGNAL(rangeChanged(QCPRange)), ui->widget->yAxis2, SLOT(setRange(QCPRange)));
    // 实时更新槽函数
    _pTimerUpdate = new QTimer(this);
    connect(_pTimerUpdate, SIGNAL(timeout()), this, SLOT(customsplot_init()));



}

// 绘图
void MainWindow::customsplot_init()
{
    static QTime time(QTime::currentTime());        //获取当前时间
    //计算新的数据点
    double key = time.elapsed()/1000.0;
    static double lastPointKey = 0;

    if (key-lastPointKey > 0.002) //大于2ms添加一个数据
    {
        ui->widget->graph(0)->addData(key, temperature);      //温度加到数据中
        ui->widget->graph(1)->addData(key, temperature);
        ui->widget->graph(2)->addData(key, set_temperature); //画出设定温度
        lastPointKey = key;

        QDateTime time = QDateTime::currentDateTime();//获取系统现在的时间
        QString date = time.toString("MM.dd hh:mm:ss"); //设置显示格式
        QString tempe;
        tempe = QString("%1").arg(temperature);
        insert_table(date,tempe);
    }

    ui->widget->xAxis->setRange(key, 10, Qt::AlignRight);        //设置x轴范围
    ui->widget->replot();       //画图

    // 缩放轴
     QList < QCPAxis *>  axis_x,axis_y,axis_xy;
     axis_x.append(ui->widget->xAxis);
     axis_y.append(ui->widget->yAxis);
     axis_xy.append(ui->widget->xAxis);
     axis_xy.append(ui->widget->yAxis);
     if(ui->checkBox_X->checkState())
     {
        ui->widget->axisRect()->setRangeZoomAxes(axis_x);
     }
     if(ui->checkBox_Y->checkState())
     {
        ui->widget->axisRect()->setRangeZoomAxes(axis_y);
     }
     if(ui->checkBox_XY->checkState())
     {
        ui->widget->axisRect()->setRangeZoomAxes(axis_xy);
     }


}


void MainWindow::on_start_clicked()
{
    //指示灯变绿，开始记录数据
    fitpixmap = QPixmap("://images/greenlight.png").scaled(51, 51, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
    ui->label_light->setPixmap(pixmap_to_round(fitpixmap,25.5));
    //定时器开始计时
    _pTimerUpdate->start(1000); //1s更新一次
    ui->pause->setEnabled(true);
    ui->start->setEnabled(false);
    ui->increase_temp->setEnabled(false);
    ui->decrease_temp->setEnabled(false);

    //使用联合体发送设定温度
    cout << set_temperature << endl;
    union FB{
        float f;
        char b[4];
    }fb;
    fb.f = set_temperature;
    //fb.f = 232.421;
    cout << sizeof(fb.b);
    char Tx_Buf[5];
    for(int i=0;i<4;i++){
        Tx_Buf[i]=fb.b[i];
    }
    Tx_Buf[4]='o';
    QByteArray array(Tx_Buf,5);
    serialport->write(array);


    QString current_set_temperature = ui->textEdit->toPlainText();
    QDateTime current_date_time =QDateTime::currentDateTime();   //获取当前时间
    current_set_temperature +=current_date_time.toString("yyyy.MM.dd hh:mm");
    current_set_temperature += " 设定温度" ;
    current_set_temperature += QString("%1").arg(set_temperature);
    current_set_temperature += "℃";
    current_set_temperature += "\n";
    ui->textEdit->setText(current_set_temperature);
}

void MainWindow::on_pause_clicked()
{
    //暂停，指示灯变红
    fitpixmap = QPixmap("://images/redlight.png").scaled(51, 51, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
    ui->label_light->setPixmap(pixmap_to_round(fitpixmap,25.5));
    _pTimerUpdate->stop(); //定时器暂停
    ui->pause->setEnabled(false);
    ui->start->setEnabled(true);
    ui->increase_temp->setEnabled(true);
    ui->decrease_temp->setEnabled(true);
}



void MainWindow::on_decrease_temp_clicked()
{
    set_temperature = set_temperature - 0.5;
    ui->lcdSetNum->display(set_temperature);

}

void MainWindow::on_increase_temp_clicked()
{
    set_temperature = set_temperature + 0.5;
    ui->lcdSetNum->display(set_temperature);

}

// 插入数据
void MainWindow::insert_table(QString date, QString t)
{
    update();
    int row_count = ui->tableWidget->rowCount();   //获取总行数
    ui->tableWidget->insertRow(row_count);         //插入行
    QTableWidgetItem *item0 = new QTableWidgetItem();
    QTableWidgetItem *item1 = new QTableWidgetItem();
    item0->setText(date);
    item1->setText(t);
    ui->tableWidget->setItem(row_count,0,item0);
    ui->tableWidget->setItem(row_count,1,item1);

}

//清空表
void MainWindow::on_clear_form_clicked()
{
    while(ui->tableWidget->rowCount())
    {
        ui->tableWidget->removeRow(0);
    }
}

//保存表为文本文件
void MainWindow::on_save_form_clicked()
{
    // 获取文件目录
    QString filename = QFileDialog::getSaveFileName(this, "save", "../", "TXT(*.txt)");
    if(filename.isEmpty() == false){
        //文件对象
        QFile file(filename);
        bool isOk = file.open(QIODevice::WriteOnly);
        if(true == isOk){
            //文件流对象
            QTextStream stream(&file);

            //遍历数据
            int romcount = ui->tableWidget->rowCount();     //获取总行数
            for(int i = 0; i < romcount; i++)
            {
                QString rowstring;
                for(int j = 0; j < 2; j++)
                {
                    rowstring += ui->tableWidget->item(i,j)->text();
                    rowstring += "  ";
                }
                rowstring += "\n";
                stream << rowstring;
            }

            file.close();
        }
    }
}

//打开串口
void MainWindow::on_open_port_clicked()
{

    if(ui->com->count() != 0){   //不为空时
        //初始化串口
            serialport->setPortName(ui->com->currentText());        //设置串口名
            if(serialport->open(QIODevice::ReadWrite))              //打开串口成功
            {
               serialport->setBaudRate(9600);       //设置波特率
               serialport->setDataBits(QSerialPort::Data8);
               serialport->setParity(QSerialPort::NoParity);
               serialport->setStopBits(QSerialPort::OneStop);
               serialport->setStopBits(QSerialPort::TwoStop);
               serialport->setFlowControl(QSerialPort::NoFlowControl);     //设置流控制
               QObject::connect(serialport, &QSerialPort::readyRead, this, &MainWindow::read_serialport);    //读数据
                //控件可见设置
               ui->start->setEnabled(true);
               ui->close_port->setEnabled(true);
               ui->open_port->setEnabled(false);
               ui->increase_temp->setEnabled(true);
               ui->decrease_temp->setEnabled(true);
               ui->label_state->setText(tr("串口打开成功"));

                // 操作记录
               QString current_date = ui->textEdit->toPlainText();
               QDateTime current_date_time =QDateTime::currentDateTime();   //获取当前时间
               current_date +=current_date_time.toString("yyyy.MM.dd hh:mm");
               current_date += " 打开串口" ;
               current_date += "\n";
               ui->textEdit->setText(current_date);

               ui->com->setEnabled(false);
            }
    }else //打开失败提示
     {
          QMessageBox::information(this,tr("Error"),tr("Open the failure"),QMessageBox::Ok);
          ui->label_state->setText(tr("串口未打开"));
     }
}

void MainWindow::on_close_port_clicked()
{
    //关闭串口，指示灯变红
    fitpixmap = QPixmap("://images/redlight.png").scaled(51, 51, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
    ui->label_light->setPixmap(pixmap_to_round(fitpixmap,25.5));
    ui->increase_temp->setEnabled(false);
    ui->decrease_temp->setEnabled(false);
    ui->start->setEnabled(false);
    ui->pause->setEnabled(false);
    ui->open_port->setEnabled(true);
    ui->close_port->setEnabled(false);

    ui->com->setEnabled(true);


    //关闭串口
    serialport->clear();        //清空缓存区
    serialport->close();        //关闭串口
    ui->label_state->setText(tr("串口未打开"));

    // 操作记录
    QString current_date = ui->textEdit->toPlainText();
    QDateTime current_date_time =QDateTime::currentDateTime();   //获取当前时间
    current_date +=current_date_time.toString("yyyy.MM.dd hh:mm");
    current_date += " 关闭串口" ;
    current_date += "\n\n";
    ui->textEdit->setText(current_date);

    // lcd 显示 0
    temperature = 00.00;
    ui->lcdCurNum->display(temperature);
    set_temperature = 00.00;
    ui->lcdSetNum->display(set_temperature);
}

//查找串口
void MainWindow::find_serialport()
{
    ui->com->clear();
    //查找可用的串口
    foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
    {
        QSerialPort serial;
        serial.setPort(info);   //设置串口
        if(serial.open(QIODevice::ReadWrite))
        {
            ui->com->addItem(serial.portName());        //显示串口name
            serial.close();
        }
    }
}

// 读串口数据
void MainWindow::read_serialport()
{
    union FB{
        float f;
        char b[4];
    }fb;
    //char Rx_Buf[5];
    char res;
    QByteArray buf;
    buf = serialport->readAll();
    if(!buf.isEmpty())          //显示数据
    {
//        QDataStream out(&buf,QIODevice::ReadWrite);
//        for(int i=0;i<4;i++){
//            out << fb.b[i];
//        }
        for(int i=0;i<buf.length();i++){
            res = buf[i];
            cout << res <<endl;
            if(res=='o'){
                temperature=fb.f;
                cout << temperature << endl;
            }else{
                fb.b[i]=res;
            }
        }

    }
    buf.clear();    //清空缓存区

    ui->lcdCurNum->display(temperature);
}

void MainWindow::onMouseMove(QMouseEvent* event){

    QCustomPlot* customPlot = qobject_cast<QCustomPlot*>(sender());
    double x = customPlot->xAxis->pixelToCoord(event->pos().x());
    double y = customPlot->yAxis->pixelToCoord(event->pos().y());
    textItem->setText(QString("(%1, %2)").arg(x).arg(y));
    textItem->position->setCoords(QPointF(x, y));
    textItem->setFont(QFont(font().family(), 10));
    customPlot->replot();
}

//轴缩放
void MainWindow::checkbox_change()
{
    // 缩放轴
     QList < QCPAxis*>  axis_x,axis_y,axis_xy;
     axis_x.append(ui->widget->xAxis);
     axis_y.append(ui->widget->yAxis);
     axis_xy.append(ui->widget->xAxis);
     axis_xy.append(ui->widget->yAxis);
     if(ui->checkBox_X->checkState())
     {
        ui->widget->axisRect()->setRangeZoomAxes(axis_x);
     }
     if(ui->checkBox_Y->checkState())
     {
        ui->widget->axisRect()->setRangeZoomAxes(axis_y);
     }
     if(ui->checkBox_XY->checkState())
     {
        ui->widget->axisRect()->setRangeZoomAxes(axis_xy);
     }
}


QPixmap MainWindow::pixmap_to_round(QPixmap &src,double radius)
{
    if (src.isNull()) {
           return QPixmap();
       }

    QSize size(2*radius, 2*radius);
    QBitmap mask(size);
    QPainter painter(&mask);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.setRenderHint(QPainter::SmoothPixmapTransform);
    painter.fillRect(0, 0, size.width(), size.height(), Qt::white);
    painter.setBrush(QColor(0, 0, 0));
    painter.drawRoundedRect(0, 0, size.width(), size.height(), 99, 99);

    QPixmap image = src.scaled(size);
    image.setMask(mask);
    return image;

}


